package com.hvisions.server.runner;

import com.hvisions.common.MyUaNode;
import com.hvisions.common.Tree;
import com.hvisions.config.DeviceOpenConfigProcess;
import com.hvisions.config.OpcUaConfig;
import com.hvisions.server.model.TbOpcPoint;
import com.hvisions.server.service.ITbOpcPointService;
import org.eclipse.milo.opcua.sdk.client.model.nodes.objects.FolderTypeNode;
import org.eclipse.milo.opcua.sdk.client.model.nodes.objects.ServerTypeNode;
import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ykz
 */
@Order(value = 100)
@Component
public class ApplicationRunnerImpl implements ApplicationRunner {
    @Lazy
    @Resource
    WebApplicationContext applicationContext;
    @Lazy
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    Redisson redisson;

    @Autowired
    DeviceOpenConfigProcess process;

    @Autowired
    OpcUaConfig opcUaConfig;

    @Autowired
    ITbOpcPointService tbOpcPointService;

    public static Boolean send = false;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        //从表里同步订阅点信息
        List<TbOpcPoint> list = tbOpcPointService.list();
        redisTemplate.delete("opc:point");
        if(list.size()>0){
            redisTemplate.opsForList().rightPushAll("opc:point",list.stream().map(t-> t.getPoint()).collect(Collectors.toList()));
        }
        opcUaConfig.createSubscription(true);
        process.run();
        RLock opc = redisson.getLock("opc");
        //redisson锁 服务高可用，避免多个opc服务启动后，同时订阅同时发送数据到值数据重复的问题
        RLock rLock = redisson.getLock("cjxjy-wareHouse-project");
        if(rLock.tryLock()){
            send = true;
        }
    }
}
